package com.yj.rselasticsearch.service.impl;

import com.google.common.collect.Maps;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yj.common.constant.DataConstants;
import com.yj.common.constant.DataScopeConstants;
import com.yj.common.constant.HttpStatus;
import com.yj.common.core.domain.AjaxResult;
import com.yj.common.core.domain.entity.*;
import com.yj.common.core.domain.model.LoginUser;
import com.yj.common.exception.ServiceException;
import com.yj.common.utils.FastUtils;
import com.yj.common.utils.SecurityUtils;
import com.yj.common.utils.StringUtils;
import com.yj.rselasticsearch.domain.dto.FileTypeDto;
import com.yj.rselasticsearch.domain.vo.DataCopeDto;
import com.yj.rselasticsearch.domain.vo.DeptVo;
import com.yj.rselasticsearch.domain.vo.MemberVo;
import com.yj.rselasticsearch.domain.vo.SysDeptFileType;
import com.yj.rselasticsearch.service.FileInfoService;
import com.yj.rselasticsearch.service.TokenService;
import com.yj.system.domain.SysRoleDept;
import com.yj.system.mapper.SysRoleDeptMapper;
import com.yj.system.service.ISysDeptService;
import com.yj.system.service.ISysRoleService;
import com.yj.system.service.ISysUserService;
import com.yj.system.service.SysRoleFileTypeService;
import com.yj.system.service.impl.SysRoleServiceImpl;
import com.zaxxer.hikari.util.FastList;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.yj.rselasticsearch.mapper.FileTypeMapper;
import com.yj.rselasticsearch.service.FileTypeService;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FileTypeServiceImpl extends ServiceImpl<FileTypeMapper, FileType> implements FileTypeService {
    @Resource
    private ISysRoleService sysRoleService;

    @Resource
    private ISysDeptService deptService;

    @Resource
    private TokenService tokenService;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private SysRoleDeptMapper deptMapper;

    @Resource
    private ISysDeptService sysDeptService;

    @Resource
    private FileInfoService fileInfoService;

    @Resource
    private SysRoleFileTypeService roleFileTypeService;

    @Override
    public AjaxResult fileTypeList() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        //查询文件类型
        List<FileType> fileTypeList = this.list(new LambdaQueryWrapper<FileType>().eq(FileType::getStatus, DataConstants.Number.ZERO));
        List<SysRoleDept> sysRoleDepts = getRoleDepts(null).getSysRoleDepts();
        List<SysRoleFileType> roleFileTypes = getRoleDepts(null).getFileTypes();
        String dataScope = getRoleDepts(null).getDataScope();
        //数据过滤
        List<FileType> types = new ArrayList<>();
        List<FileType> newCurrentFileType = new ArrayList<>();
        if (!loginUser.getUser().isAdmin()) {
            if (!FastUtils.checkNullOrEmpty(sysRoleDepts) && !DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF.equals(dataScope)) {
                for (FileType fileType : fileTypeList) {
                    for (SysRoleDept sysRoleDept : sysRoleDepts) {
                        if (fileType.getFileTypeDepId().toString().equals(sysRoleDept.getDeptId().toString())) {
                            types.add(fileType);
                            break;
                        }
                    }
                }
            } else if (DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF.equals(dataScope)) {
                for (FileType fileType : fileTypeList) {
                    if (loginUser.getUser().getUserName().equals(fileType.getCreateBy())) {
                        types.add(fileType);
                    }
                }
            } else {
                types = fileTypeList;
            }

            for (FileType fileType : types) {
                for (SysRoleFileType sysRoleFileType : roleFileTypes) {
                    if (fileType.getFileTypeId().toString().equals(sysRoleFileType.getFileTypeId().toString())) {
                        newCurrentFileType.add(fileType);
                        break;
                    }
                }
            }
        } else {
            //管理员看所有
            newCurrentFileType = fileTypeList;
        }
        //数据分组
        List<SysDept> sysDept = deptService.selectDeptListVo();
        newCurrentFileType.forEach(data -> {
            sysDept.forEach(dept -> {
                if (data.getFileTypeDepId().equals(dept.getDeptId())) {
                    data.setFileTypeDepName(dept.getDeptName());
                }
            });
        });
        return AjaxResult.success(newCurrentFileType);
    }

    @Override
    public AjaxResult deptFileTypeList() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        //查询文件类型
        List<FileType> fileTypeList = this.list(new LambdaQueryWrapper<FileType>().eq(FileType::getStatus, DataConstants.Number.ZERO));
        List<SysRoleDept> sysRoleDepts = getRoleDepts(null).getSysRoleDepts();
        List<SysRoleFileType> roleFileTypes = getRoleDepts(null).getFileTypes();
        String dataScope = getRoleDepts(null).getDataScope();
        //数据过滤
        List<FileType> types = new ArrayList<>();
        List<FileType> newCurrentFileType = new ArrayList<>();
        if (!loginUser.getUser().isAdmin()) {
            if (!FastUtils.checkNullOrEmpty(sysRoleDepts) && !DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF.equals(dataScope)) {
                for (FileType fileType : fileTypeList) {
                    for (SysRoleDept sysRoleDept : sysRoleDepts) {
                        if (fileType.getFileTypeDepId().toString().equals(sysRoleDept.getDeptId().toString())) {
                            types.add(fileType);
                            break;
                        }
                    }
                }
            } else if (DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF.equals(dataScope)) {
                for (FileType fileType : fileTypeList) {
                    if (loginUser.getUser().getUserName().equals(fileType.getCreateBy())) {
                        types.add(fileType);
                    }
                }
            } else {
                types = fileTypeList;
            }

            for (FileType fileType : types) {
                for (SysRoleFileType sysRoleFileType : roleFileTypes) {
                    if (fileType.getFileTypeId().toString().equals(sysRoleFileType.getFileTypeId().toString())) {
                        newCurrentFileType.add(fileType);
                        break;
                    }
                }
            }
        } else {
            //管理员看所有
            newCurrentFileType = fileTypeList;
        }
        //数据分组
        List<SysDept> sysDept = deptService.selectDeptListVo();
        newCurrentFileType.forEach(data -> {
            sysDept.forEach(dept -> {
                if (data.getFileTypeDepId().equals(dept.getDeptId())) {
                    data.setFileTypeDepName(dept.getDeptName());
                }
            });
        });

        List<DeptVo> sysDeptFileTypes = new ArrayList<>();
        List<SysDept> sysDepts = deptService.selectDeptListVo();
        //添加部门
        newCurrentFileType.forEach(data->{
            sysDepts.forEach(dept->{
                if (data.getFileTypeDepId().toString().equals(dept.getDeptId().toString())){
                    if (!FastUtils.checkNullOrEmpty(sysDeptFileTypes)){
                        boolean isHas = false;
                        for (DeptVo sysDeptFileType : sysDeptFileTypes) {
                            if (sysDeptFileType.getDeptId().toString().equals(dept.getDeptId().toString())){
                                isHas = true;
                            }
                        }
                        if (!isHas){
                            DeptVo deptVo = new DeptVo();
                            deptVo.setDeptId(dept.getDeptId());
                            deptVo.setDeptName(dept.getDeptName());
                            sysDeptFileTypes.add(deptVo);
                        }
                    }else{
                        DeptVo deptVo = new DeptVo();
                        deptVo.setDeptId(dept.getDeptId());
                        deptVo.setDeptName(dept.getDeptName());
                        sysDeptFileTypes.add(deptVo);
                    }
                }
            });
        });
        if (!FastUtils.checkNullOrEmpty(sysDeptFileTypes)){
            for (DeptVo sysDeptFileType : sysDeptFileTypes) {
                List<FileType> fileTypes = new ArrayList<>();
                newCurrentFileType.forEach(f->{
                    if (sysDeptFileType.getDeptId().toString().equals(f.getFileTypeDepId().toString())){
                        fileTypes.add(f);

                    }
                });
                sysDeptFileType.setFileTypeList(fileTypes);
            }
        }
        return AjaxResult.success(sysDeptFileTypes);
    }

    @Override
    public AjaxResult getFileTypeListByUser(HttpServletRequest request) {
        SysUser sysUser = getUserInfo(request);
        SysDeptFileType sysDeptFileType = new SysDeptFileType();
        //获取所有分类
        List<FileType> fileTypes = list(new LambdaQueryWrapper<FileType>().eq(FileType::getStatus, 0));
        //将分类按部门分类
        List<FileType> currentFileTypes = new ArrayList<>();
        List<SysRoleDept> sysRoleDepts = getRoleDepts(sysUser).getSysRoleDepts();
        List<SysRoleFileType> roleFileTypes = getRoleDepts(sysUser).getFileTypes();
        List<SysDept> sysDept = deptService.selectDeptListVo();
        //给分类信息赋值名称
        fileTypes.forEach(data -> {
            sysDept.forEach(dept -> {
                if (data.getFileTypeDepId().equals(dept.getDeptId())) {
                    data.setFileTypeDepName(dept.getDeptName());
                }
            });
        });
        //数据权限
        String dataScope = getRoleDepts(sysUser).getDataScope();
        if (!FastUtils.checkNullOrEmpty(sysRoleDepts) && !DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF.equals(dataScope)) {
            for (FileType fileType : fileTypes) {
                for (SysRoleDept sysRoleDept : sysRoleDepts) {
                    if (fileType.getFileTypeDepId().toString().equals(sysRoleDept.getDeptId().toString())) {
                        currentFileTypes.add(fileType);
                        break;
                    }
                }
            }
        } else if (DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF.equals(dataScope)) {
            for (FileType fileType : fileTypes) {
                for (SysRoleFileType roleFileType : roleFileTypes) {
                    if (fileType.getFileTypeId().toString().equals(roleFileType.getFileTypeId().toString())) {
                        currentFileTypes.add(fileType);
                        break;
                    }
                }
            }
        } else {
            currentFileTypes = fileTypes;
        }
        List<FileType> newCurrentFileType = new ArrayList<>();
        log.info("roleFileTypes：%s", roleFileTypes.size());
        for (FileType fileType : currentFileTypes) {
            for (SysRoleFileType sysRoleFileType : roleFileTypes) {
                log.info(String.format("数据得id：%s,权限得数据id:%s", fileType.getFileTypeId().toString(), sysRoleFileType.getFileTypeId().toString()));
                if (fileType.getFileTypeId().toString().equals(sysRoleFileType.getFileTypeId().toString())) {
                    newCurrentFileType.add(fileType);
                    break;
                }
            }
        }
        sysDeptFileType.setCurrentDeptFileType(newCurrentFileType);
        //将分类按部门分类
        List<DeptVo> deptVos = new ArrayList<>();
        //添加部门信息
        for (FileType fileType : fileTypes) {
            DeptVo deptVo = new DeptVo();
            deptVo.setDeptId(fileType.getFileTypeDepId().longValue());
            if (!FastUtils.checkNull(deptVo.getDeptId())) {
                SysDept dept = deptService.selectDeptById(deptVo.getDeptId().longValue());
                deptVo.setDeptName(dept.getDeptName());
                deptVos.add(deptVo);
            }
        }
        //部门信息根据id去重
        deptVos = deptVos.stream().collect(
                Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(DeptVo::getDeptId))), ArrayList::new)
        );
        //数据分组
        //添加分类信息
        for (DeptVo deptVo : deptVos) {
            List<FileType> fileTypes2 = new ArrayList<>();
            for (FileType fileType : fileTypes) {
                if (fileType.getFileTypeDepId().toString().equals(deptVo.getDeptId().toString())) {
                    fileTypes2.add(fileType);
                }
            }
            deptVo.setFileTypeList(fileTypes2);
        }
        sysDeptFileType.setDeptVos(deptVos);
        return AjaxResult.success(sysDeptFileType);
    }


    /**
     * 获取当前微信登录用户
     *
     * @param request
     * @return
     */
    public SysUser getUserInfo(HttpServletRequest request) {
        MemberVo user = (MemberVo) tokenService.getLoginUser(request);
        SysUser sysUser = null;
        if (FastUtils.checkNull(user)) {
            throw new ServiceException("未获取到登录信息，请登录！", HttpStatus.UNAUTHORIZED);
        } else {
            if (FastUtils.checkNull(user.getPhone())) {
                throw new ServiceException("未获取到登录手机号，请重新登录！", HttpStatus.UNAUTHORIZED);
            }
            sysUser = sysUserService.selectUserByPhone(user.getPhone());
            if (FastUtils.checkNull(sysUser)) {
                throw new ServiceException("权限不足，请联系管理员！", HttpStatus.UNAUTHORIZED);
            } else {
                if (DataConstants.Number.ONE.equals(sysUser.getIsMiniProgram())) {
                    throw new ServiceException("您当前没有权限访问此应用！", HttpStatus.UNAUTHORIZED);
                }
            }
        }
        return sysUser;
    }


    /**
     * 获取当前登录用户数据权限信息
     *
     * @return
     */
    @Override
    public DataCopeDto getRoleDepts(SysUser SysUser) {
        DataCopeDto dataCopeDto = new DataCopeDto();
        List<SysRoleDept> sysRoleDepts = new ArrayList<>();
        //获取当前用户数据权限
        LoginUser loginUser = null;
        if (SysUser == null) {
            try {
                loginUser = SecurityUtils.getLoginUser();
            } catch (Exception ex) {
                log.info(ex.getMessage());
            }
        }
        List<SysRoleFileType> roleFileTypes = new ArrayList<>();
        String dataScope = null;
        SysUser currentUser = null;
        if (!FastUtils.checkNull(loginUser)) {
            currentUser = loginUser.getUser();
        } else {
            currentUser = SysUser;
        }
        // 如果是超级管理员，则不过滤数据
        if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {
            List<SysRole> role = currentUser.getRoles();
            if (FastUtils.checkNull(role)) {
                role = sysRoleService.selectRolesByUserIds(currentUser.getUserId());
            }
            if (!FastUtils.checkNullOrEmpty(role)) {
                for (SysRole sysRole : role) {
                    if (DataConstants.Number.ONE.toString().equals(sysRole.getStatus())) {
                        continue;
                    }
                    if (!StringUtils.isEmpty(sysRole.getDataScope())) {
                        dataScope = sysRole.getDataScope();
                    }
                    List<SysRoleFileType> fileTypes1 = roleFileTypeService.list(new LambdaQueryWrapper<SysRoleFileType>().eq(SysRoleFileType::getRoleId, sysRole.getRoleId().intValue()));
                    if (!FastUtils.checkNull(fileTypes1)) {
                        roleFileTypes.addAll(fileTypes1);
                    }
                    //dataScope
                    if (sysRole.getDataScope().equals(DataScopeConstants.DATASCOPE.DATA_SCOPE_ALL)) {
                        //全部数据
                        continue;
                    } else if (sysRole.getDataScope().equals(DataScopeConstants.DATASCOPE.DATA_SCOPE_CUSTOM)) {
                        //自定义数据权限
                        List<SysRoleDept> depts = deptMapper.queryAllByRoleId(sysRole.getRoleId());
                        sysRoleDepts.addAll(depts);
                    } else if (sysRole.getDataScope().equals(DataScopeConstants.DATASCOPE.DATA_SCOPE_DEPT)) {
                        //本部门数据权限
                        SysRoleDept sysRoleDept = new SysRoleDept();
                        sysRoleDept.setDeptId(currentUser.getDeptId());
                        sysRoleDepts.add(sysRoleDept);
                    } else if (sysRole.getDataScope().equals(DataScopeConstants.DATASCOPE.DATA_SCOPE_DEPT_AND_CHILD)) {
                        //本部门及以下数据权限
                        SysRoleDept sysRoleDept = new SysRoleDept();
                        sysRoleDept.setDeptId(currentUser.getDeptId());
                        sysRoleDepts.add(sysRoleDept);
                        //查询当前部门下所有子级部门
                        List<SysDept> sysDepts = sysDeptService.selectDeptListVo();
                        getChildren(currentUser.getDeptId().toString(), sysDepts, sysRoleDepts);
                    } else if (sysRole.getDataScope().equals(DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF)) {
                        SysRoleDept sysRoleDept = new SysRoleDept();
                        sysRoleDept.setDataScope(DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF);
                        sysRoleDepts.add(sysRoleDept);
                    }
                }
            }

        }
        //角色部门数据去重
        if (sysRoleDepts.size() > 1) {
            sysRoleDepts = sysRoleDepts.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SysRoleDept::getDeptId))), ArrayList::new));
        }
        if (roleFileTypes.size() > 1) {
            roleFileTypes = roleFileTypes.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SysRoleFileType::getFileTypeId))), ArrayList::new));
        }
        Map<String, List<Object>> map = new HashMap<>();
        dataCopeDto.setFileTypes(roleFileTypes);
        dataCopeDto.setSysRoleDepts(sysRoleDepts);
        dataCopeDto.setDataScope(dataScope);
        return dataCopeDto;
    }

    //递归子节点部门
    private void getChildren(String id, List<SysDept> depts, List<SysRoleDept> sysRoleDepts) {
        List<SysDept> sysDepts = new ArrayList<>();
        sysDepts.addAll(depts);
        //存放子节点数据
        depts.forEach(data -> {
            if (data.getParentId().toString().equals(id)) {
                SysRoleDept sysRoleDept = new SysRoleDept();
                sysRoleDept.setDeptId(data.getDeptId());
                sysRoleDepts.add(sysRoleDept);
                sysDepts.remove(data);
            }
        });
        if (!CollectionUtils.isEmpty(sysDepts) && depts.size() != sysDepts.size()) {
            for (SysRoleDept sysRoleDept : sysRoleDepts) {
                if (!CollectionUtils.isEmpty(sysDepts)) {
                    getChildren(sysRoleDept.getDeptId().toString(), sysDepts, sysRoleDepts);
                }
                break;
            }
        }
    }

    /**
     * 分页查询文件类型信息
     *
     * @param fileTypeDto
     * @return
     */
    @Override
    public AjaxResult getFileTypeByPage(FileTypeDto fileTypeDto) {
        IPage<FileType> fileInfoPage = new Page<>(fileTypeDto.getPageIndex(), fileTypeDto.getPageSize());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<SysRoleDept> sysRoleDepts = getRoleDepts(null).getSysRoleDepts();
        List<SysRoleFileType> roleFileTypes = getRoleDepts(null).getFileTypes();
        //查询文件类型
        List<FileType> fileTypeList = this.list(new LambdaQueryWrapper<FileType>().
                eq(FileType::getStatus, DataConstants.Number.ZERO).
                eq(fileTypeDto.getFileTypeDepId() != null, FileType::getFileTypeDepId, fileTypeDto.getFileTypeDepId()).orderByDesc(FileType::getCreateTime));
        //数据过滤
        List<FileType> types = new ArrayList<>();
        List<FileType> fileTypes = new ArrayList<>();
        if (!loginUser.getUser().isAdmin()) {
            String dataScope = getRoleDepts(null).getDataScope();
            if (!FastUtils.checkNullOrEmpty(sysRoleDepts) && !DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF.equals(dataScope)) {
                for (FileType fileType : fileTypeList) {
                    for (SysRoleDept sysRoleDept : sysRoleDepts) {
                        if (fileType.getFileTypeDepId().equals(sysRoleDept.getDeptId())) {
                            types.add(fileType);
                            break;
                        }
                    }
                }
            } else if (DataScopeConstants.DATASCOPE.DATA_SCOPE_SELF.equals(dataScope)) {
                for (FileType fileType : fileTypeList) {
                    if (fileType.getCreateBy().equals(loginUser.getUsername())) {
                        types.add(fileType);
                    }
                }
            } else {
                types = fileTypeList;
            }
            //数据分组
            List<SysDept> sysDept = deptService.selectDeptListVo();
            types.forEach(data -> {
                sysDept.forEach(dept -> {
                    if (data.getFileTypeDepId().equals(dept.getDeptId())) {
                        data.setFileTypeDepName(dept.getDeptName());
                    }
                });
            });
            List<SysDept> sysDeptList = sysDeptService.selectDeptListVo();
            fileTypeList.forEach(data -> {
                sysDeptList.forEach(dept -> {
                    if (String.valueOf(data.getFileTypeDepId()).equals(String.valueOf(dept.getDeptId()))) {
                        data.setFileTypeDepName(dept.getDeptName());
                    }
                });
            });

            //文档类型过滤
            if (!FastUtils.checkNull(roleFileTypes)) {
                for (SysRoleFileType roleFileType : roleFileTypes) {
                    for (FileType fileType : fileTypeList) {
                        if (fileType.getFileTypeId().toString().equals(roleFileType.getFileTypeId().toString())) {
                            fileTypes.add(fileType);
                        }
                    }
                }
            } else {
                fileTypes = fileTypeList;
            }
        } else {
            fileTypes = fileTypeList;
        }
        //查询全部所有文件信息
        //分页信息
        fileInfoPage.setTotal(fileTypes.size());
        fileInfoPage.setCurrent(fileTypeDto.getPageIndex());
        fileInfoPage.setSize(fileTypeDto.getPageSize());
        fileInfoPage.setPages(fileInfoPage.getTotal() % fileTypeDto.getPageSize());
        int fromIndex = ((int) fileInfoPage.getCurrent() - 1) * (int) fileInfoPage.getSize(); //第几行数据开始
        int toIndex = fromIndex + (int) fileInfoPage.getSize(); //第几行结束
        if (toIndex > (int) fileInfoPage.getTotal()) {
            toIndex = (int) fileInfoPage.getTotal();
        }
        List<FileType> pageList = fileTypes.subList(fromIndex, toIndex);
        fileInfoPage.setRecords(pageList);
        return AjaxResult.success(fileInfoPage);
    }

}
